package com.youlu.campus.service.activity.impl;

import com.youlu.campus.entity.CertificateActivityConfig;
import com.youlu.campus.entity.PayButtonConfigPage;
import com.youlu.campus.entity.PayConfigPage;
import com.youlu.campus.entity.VO.req.ActivityPayButtonConfigVO;
import com.youlu.campus.entity.VO.req.CopyPayConfigPageReq;
import com.youlu.campus.service.ca.impl.CertificateActivityConfigService;
import com.youlu.campus.service.cache.CachePayConfigService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.repository.support.PageableExecutionUtils;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class ActivityPayButtonConfigService {

    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private CachePayConfigService cachePayConfigService;

    @Autowired
    private CertificateActivityConfigService certificateActivityConfigService;


    public Map<String, List<CertificateActivityConfig>> availActivity(){
        Date now = new Date();
        Query query = new Query();
        query.addCriteria(Criteria.where("buttonType").is(PayButtonConfigPage.PAPER_CERTIFICATE));
        query.addCriteria(Criteria.where("startTime").lte(now));
        query.addCriteria(Criteria.where("endTime").gte(now));
        List<PayButtonConfigPage> buttonConfigList = this.mongoTemplate.find(query, PayButtonConfigPage.class);
        if(CollectionUtils.isEmpty(buttonConfigList)){
            return null;
        }
        Set<String> certificateConfigIdSet = buttonConfigList.stream().map(buttonConfig -> buttonConfig.getCertificateConfigId()).collect(Collectors.toSet());
         if(CollectionUtils.isEmpty(certificateConfigIdSet)){
             return null;
         }
        return certificateActivityConfigService.getByIds(certificateConfigIdSet);
    }


    public void save(ActivityPayButtonConfigVO activityPayButtonConfig){
        String id = activityPayButtonConfig.getId();
        PayButtonConfigPage payButtonConfigPage = null;
        if(StringUtils.isNotBlank(id)){
             payButtonConfigPage = mongoTemplate.findById(id, PayButtonConfigPage.class);
             if(Objects.nonNull(payButtonConfigPage)){
                 payButtonConfigPage.setUpdatedTime(new Date());
             }
        }
        if(Objects.isNull(payButtonConfigPage)){
            payButtonConfigPage = new PayButtonConfigPage();
            payButtonConfigPage.setCreatedTime(new Date());
        }
        BeanUtils.copyProperties(activityPayButtonConfig,payButtonConfigPage);
        payButtonConfigPage.setReceiveDesc(activityPayButtonConfig.getReceiveDesc());
        mongoTemplate.save(payButtonConfigPage);
        cachePayConfigService.deletePayButton(payButtonConfigPage.getPayConfigPageId(),0);
        cachePayConfigService.deletePayButton(payButtonConfigPage.getPayConfigPageId(),1);
        cachePayConfigService.deletePayButton(payButtonConfigPage.getPayConfigPageId(),2);
        cachePayConfigService.deletePayButton(payButtonConfigPage.getPayConfigPageId(),3);
    }

    public Page<PayButtonConfigPage> findByPayConfigId(String payConfigPageId){
        Query query = new Query();
        query.addCriteria(Criteria.where("payConfigPageId").is(payConfigPageId));
        query.with(Sort.by(Sort.Direction.DESC,"priority"));
        List<PayButtonConfigPage> list = this.mongoTemplate.find(query, PayButtonConfigPage.class);
        PageRequest pageRequest = PageRequest.of(0, 100);
        if(CollectionUtils.isEmpty(list)){
            return PageableExecutionUtils.getPage(new ArrayList<>(), pageRequest, () -> 0);
        }
        return PageableExecutionUtils.getPage(list.stream().map(button->{
            String certificateConfigId = button.getCertificateConfigId();
            if(StringUtils.isNotBlank(certificateConfigId)){
                CertificateActivityConfig certificateActivityConfig = findCertificateById(certificateConfigId);
                if(Objects.nonNull(certificateActivityConfig)){
                    button.setCaType(certificateActivityConfig.getCaType());
                }
            }
            PayConfigPage payConfigPage = this.mongoTemplate.findById(payConfigPageId, PayConfigPage.class);
            if(Objects.nonNull(payConfigPage)){
                button.setActivityName(payConfigPage.getActivityName());
            }
            return button;
        }).collect(Collectors.toList()), pageRequest, () -> list.size());
    }

    private CertificateActivityConfig findCertificateById(String id){
        return this.mongoTemplate.findById(id,CertificateActivityConfig.class);
    }

    public void delete(String id){
        PayButtonConfigPage payButtonConfigPage = this.mongoTemplate.findById(id, PayButtonConfigPage.class);
        Query query = new Query();
        query.addCriteria(Criteria.where("id").is(id));
        this.mongoTemplate.remove(query,PayButtonConfigPage.class);
        cachePayConfigService.deletePayButton(payButtonConfigPage.getPayConfigPageId(),0);
        cachePayConfigService.deletePayButton(payButtonConfigPage.getPayConfigPageId(),1);
        cachePayConfigService.deletePayButton(payButtonConfigPage.getPayConfigPageId(),2);
        cachePayConfigService.deletePayButton(payButtonConfigPage.getPayConfigPageId(),3);
    }


    public PayButtonConfigPage detail(String id){
        PayButtonConfigPage payButtonConfigPage = mongoTemplate.findById(id, PayButtonConfigPage.class);
        if(Objects.isNull(payButtonConfigPage)){
            return null;
        }
        if(StringUtils.isNotBlank(payButtonConfigPage.getCertificateConfigId())){
            CertificateActivityConfig certificateActivityConfig = findCertificateById(payButtonConfigPage.getCertificateConfigId());
            if(Objects.nonNull(certificateActivityConfig)){
                payButtonConfigPage.setCaType(certificateActivityConfig.getCaType());
            }
        }
        return payButtonConfigPage;
    }

    public void doCopyPayButtonConfig(CopyPayConfigPageReq copyPayConfigPageReq) {
        String copyActivityId = copyPayConfigPageReq.getCopyActivityId();
        String oldPayConfigPageId = copyPayConfigPageReq.getOldPayConfigPageId();
        log.info("【copy 活动】开始复制活动支付配置按钮->{} copyActivityId", copyActivityId);
        Query query = new Query();
        query.addCriteria(Criteria.where("payConfigPageId").is(oldPayConfigPageId));
        List<PayButtonConfigPage> list = this.mongoTemplate.find(query, PayButtonConfigPage.class);
        if(CollectionUtils.isEmpty(list)){
            log.error("【copy 活动】结束复制活动支付配置按钮->{} 未查询到 copyActivityId", copyActivityId);
            return;
        }
        query = new Query();
        query.addCriteria(Criteria.where("activityId").is(copyPayConfigPageReq.getNewActivityId()));
        List<CertificateActivityConfig> configList = this.mongoTemplate.find(query, CertificateActivityConfig.class);
        Date now = new Date();
        List<PayButtonConfigPage> targetPayButtonConfigPageList = list.stream().peek(payButtonConfigPage -> {
            payButtonConfigPage.setId(null);
            payButtonConfigPage.setCreatedTime(now);
            payButtonConfigPage.setUpdatedTime(now);
            payButtonConfigPage.setActivityId(copyPayConfigPageReq.getNewActivityId());
            payButtonConfigPage.setPayConfigPageId(copyPayConfigPageReq.getNewPayConfigPageId());
            if (CollectionUtils.isNotEmpty(configList)) {
                CertificateActivityConfig certificateActivityConfig1 =
                        configList.stream().filter(certificateActivityConfig -> certificateActivityConfig.getCaType().equals(payButtonConfigPage.getCaType())).findFirst().orElse(null);
                if (Objects.nonNull(certificateActivityConfig1)) {
                    payButtonConfigPage.setCertificateConfigId(certificateActivityConfig1.getId());
                }
            }
        }).collect(Collectors.toList());
        this.mongoTemplate.insertAll(targetPayButtonConfigPageList);
        log.info("【copy 活动】结束复制活动支付配置按钮->{} copyActivityId", copyActivityId);
    }

}
